import { App } from "../App";
import { Singleton } from "./Class";
import { EventConst } from "./EventConst";
import Map from "./Map";

/**
 * 对媒体管理类
 *
 * @interface item
 */

const MIN_VOL: number = 0.1;
const MAX_VOL: number = 1.0;

export default class AudioMgr extends Singleton<AudioMgr> {
    private _volEffect: number = MAX_VOL;
    private _volMusic: number = MAX_VOL;
    private _curPlayID:number = null;
    private _isHide:boolean = false;
    private _effectID:number = null;
    private _files: any = {};

    protected onInit(){
        let _cfg = App.getLocalStorage(App.LOCAL_KEY.AUDIO);
        this._volEffect = _cfg['sound'];
        this._volMusic = _cfg['music'];
        !_cfg && App.setLocalStorage({effect:MAX_VOL,music:MAX_VOL},App.LOCAL_KEY.AUDIO);
        cc.audioEngine.setEffectsVolume(this._volEffect);
        cc.audioEngine.setMusicVolume(this._volMusic);

        App.Event.on(EventConst.APP_HIDE,()=>{
            this._isHide = true;
            this._curPlayID && cc.audioEngine.pause(this._curPlayID);
        },this);
        App.Event.on(EventConst.APP_SHOW,()=>{
            this._isHide = false;
            (this._curPlayID && this._volMusic > 0) && cc.audioEngine.resume(this._curPlayID);
        },this);
    }

    protected onDestroy(){
        this._files = {};
    }

    /**
     * 播放
     * @param filePath 文件名
     * @param isEffect 是否音效
     */
    public play(file: string | cc.AudioClip, isEffect: boolean = true): void {
        if (App.Util.isInvalid(file))
            return;

        !isEffect && cc.audioEngine.stopMusic();
        let _play = (clip: cc.AudioClip) => {
            (!isEffect && this._curPlayID) && cc.audioEngine.stop(this._curPlayID);
            if (App.Util.isInvalid(clip)) return;
            isEffect ? cc.audioEngine.playEffect(clip, false) : (this._curPlayID = cc.audioEngine.playMusic(clip, true));
        };

        if (file instanceof cc.AudioClip) {
            _play(file);
            return;
        } else {
            let clip = this._files[file];
            if (clip) {
                _play(clip);
                return;
            } else {
                App.Res.loadRes(file,cc.AudioClip,(clip: cc.AudioClip)=>{
                    this._files[file] = clip;
                    _play(clip);
                });
            }
        }
    };

    public playLoopEffect(file: string | cc.AudioClip){
        if (this._volEffect <= 0) return ;
        this.stopLoopEffect();
        const _play = (clip: cc.AudioClip) => {
            if (!clip) return ;
            this._effectID = cc.audioEngine.playEffect(clip, true);
        };
        if (typeof(file) === 'string'){
            const clip = this._files[file];
            if (App.Util.isValid(clip)){
                _play(clip);
                return ;
            }
            App.Res.loadRes(file,cc.AudioClip,(clip: cc.AudioClip)=>{
                this._files[file] = clip;
                _play(clip);
            });
        } else if (file instanceof cc.AudioClip) {
            _play(file);
            return;
        }
    }

    public stopLoopEffect(){
        if (App.Util.isValid(this._effectID)){
            cc.audioEngine.stopEffect(this._effectID);
            this._effectID = null;
        }
    }

    /**
     * 设置音乐（效）音量
     * @param volMusic 音乐音量
     * @param volEffect 音效音量
     */
    public setVolume(volMusic: number, volEffect: number): void {
        cc.audioEngine.setMusicVolume(volMusic);
        cc.audioEngine.setEffectsVolume(volEffect);
        this._volMusic = volMusic;
        this._volEffect = volEffect;
        App.setLocalStorage({sound :this._volEffect,music:this._volMusic},App.LOCAL_KEY.AUDIO);
    };

    /**
     * 停止所有播放
     */
    public stopPlayAll(): void {
        cc.audioEngine.setMusicVolume(0);
        cc.audioEngine.setEffectsVolume(0);
        App.setLocalStorage({sound :0,music:0},App.LOCAL_KEY.AUDIO);
    };

    /**
     * 获取音量，包括音乐和音效
     */
    public getVolumes(): any {
        return { sound: this._volEffect, music: this._volMusic };
    };

    /**
     * 随机播放指定数组音乐
     * @param arr 播放文件数组
     */
    public randomPlayDir(paths:string[]): void {
        if (!paths || paths.length < 1) return ;
        App.Util.isValid(this._curPlayID) && cc.audioEngine.stop(this._curPlayID);
        paths = App.Util.confusionArray(paths);
        let first:boolean = false;
        const lstClip:cc.AudioClip[] = [];
        const _play = (clip: cc.AudioClip) => {
            if (!clip) return ;
            this._curPlayID = cc.audioEngine.play(clip, false, this._volMusic);
            cc.audioEngine.setFinishCallback(this._curPlayID, () => {
                _play(App.Util.randomArray(lstClip));
            })
        };
        paths.forEach((path:string)=>{
            App.Res.loadRes(path,cc.AudioClip,(clip:cc.AudioClip)=>{
                lstClip.push(clip);
                if (!first){
                    first = true;
                    _play(clip);
                }
            });
        });
    };
};
